package org.example;

import com.google.gson.Gson;
import com.itextpdf.awt.geom.AffineTransform;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.*;

import org.example.util.SignBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * pdf签字
 *
 * @author Mr.靓仔
 */
public class App {
    private static final Logger logger = LoggerFactory.getLogger(App.class);
    /**
     * 签字配置文件路径
     */
    public static String signConfigPath = "D:\\Siemens\\Teamcenter14\\teamcenter_root\\bin\\Signature_config";
    /**
     * 签名信息文件夹路径
     */
    public static String signImgPath = "D:\\Siemens\\Teamcenter14\\teamcenter_root\\bin\\Signature_jpgs";

    public static String ALL_PAGE_SIGN = "0";
    public static String NO_NEED = "-1";

    public  static float width = 50;
    public static float height = 20;

    public static  float fontSize = 12;
    public static PdfReader reader;
    public static PdfStamper stamper;

    public static void main(String[] args) throws IOException, DocumentException {
        logger.info("签字开始了");
        //handler 传入2个路径 一个pdf的 一个json.txt的 json解析出类型，页签字信息，map
        if (args.length != 2) {
            logger.info("请传参数pdf路径和签字信息路径2个参数");
            return;
            }
        //文件路径
        // String filePath = "C:\\Users\\79343\\Desktop\\123.pdf";
        String filePath = args[0];
        String signPath = args[1];
         // String signPath = "C:\\Users\\79343\\Desktop\\signinfo.json";
        logger.info("pdf路径：" + filePath);
        logger.info("签字信息路径：" + signPath);
        //读取配置文件夹
        //图片 名字：路径
        Map<String, String> signImgMap = getConfigMap(signImgPath);
        //类型 路径
        Map<String, String> signConfigMap = getConfigMap(signConfigPath);
        if (signImgMap.isEmpty() || signConfigMap.isEmpty()) {
            logger.error("配置为空或者签名图片为空");
            return;
        }

        //传入签字信息文件路径
        String json = readFileByCharCode(signPath, "UTF-8");
        logger.info("签字信息：" + json);
        Gson gson = new Gson();
        SignBean signBean = gson.fromJson(json, SignBean.class);
        //读取对应的模板配置文件
        logger.info("类型：" + signBean.getPdfType());
        String configFilePath = signConfigMap.get(signBean.getPdfType());
        if (configFilePath == null) {
            logger.error("该模板坐标配置文件" + signBean.getPdfType() + ".txt为不存在");
            return;
        }

        String config = readFileByCharCode(configFilePath, "UTF-8");
        logger.info("坐标配置:" + config);

        String[] configs = config.split("\n");
        String pageNum = configs[0];
        logger.info("pageNum=" + pageNum);

        Map<String, String> usedParams = new HashMap<>();
        try {
            reader = new PdfReader(Files.newInputStream(Paths.get(filePath)));

            //pdf页数
            int total = reader.getNumberOfPages();

            logger.info("PDF total=" + total);
            if (total < Integer.parseInt(pageNum.trim())) {
                logger.error("输入的签字页数比pdf的总页数大");
                return;
            }

            stamper = new PdfStamper(reader, Files.newOutputStream(Paths.get(filePath)));

            if (ALL_PAGE_SIGN.equals(pageNum.trim())) {
                logger.info("all need sign");
                for (int i = 1; i <= total; i++) {
                    usedParams.clear();
                    String userid = null;
                    String time = null;
                    String x = null;
                    String y = null;
                    String x1 = null;
                    String y1 = null;
                    for (String sign : signBean.getSignInfo()) {
                        String[] split = sign.split(",");
                        for (int k = 1; k < configs.length; k++) {
                            if (configs[k].trim().startsWith(split[0].trim()) && !usedParams.containsKey(configs[k].trim())) {
                                String[] split1 = configs[k].split(",");
                                userid = split[1].trim();
                                time = split[2].trim();
                                x = split1[1].trim();
                                y = split1[2].trim();
                                x1 = split1[3].trim();
                                y1 = split1[4].trim();
                                usedParams.put(configs[k].trim(), userid);
                                String img = signImgMap.get(userid);
                                if (img != null) {
                                    PdfContentByte overContent = stamper.getOverContent(i);

                                    doSignal(overContent, img, Float.parseFloat(x), Float.parseFloat(y),time,x1,y1);

                                    logger.info(userid + "在(" + x + "," + y + ")签名了,"+time  + "("+x1 + ","+y1 + ")");
                                    break;
                                } else {
                                    logger.info("签名图" + userid + "没有,无法签名");
                                }
                            }
                        }

                    }

                }
            } else {
                logger.info("need sign :" + pageNum);
                String userid = null;
                String time = null;
                String x = null;
                String y = null;
                String x1 = null;
                String y1 = null;
                for (String sign : signBean.getSignInfo()) {
                    String[] split = sign.split(",");
                    for (int k = 1; k < configs.length; k++) {
                        if (configs[k].trim().startsWith(split[0].trim()) && !usedParams.containsKey(configs[k].trim())) {
                            String[] split1 = configs[k].split(",");
                            userid = split[1].trim();
                            time=split[2].trim();
                            x = split1[1].trim();
                            y = split1[2].trim();
                            x1 = split1[3].trim();
                            y1 = split1[4].trim();
                            usedParams.put(configs[k].trim(), userid);
                            String img = signImgMap.get(userid);
                            if (img != null) {
                                PdfContentByte overContent = stamper.getOverContent(Integer.parseInt(pageNum.trim()));
                                doSignal(overContent, img, Float.parseFloat(x), Float.parseFloat(y),time,x1,y1);

                                logger.info(userid + "在(" + x + "," + y + ")签名了,"+time  + "("+x1 + ","+y1 + ")");
                                break;
                            } else {
                                logger.info("签名图" + userid + "没有,无法签名");
                            }


                        }
                    }
                }
            }
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();

            System.out.println("签字结束");
            logger.info("签字结束");
        } catch (Exception e) {
            stamper.close();
            reader.close();
            logger.error("签名出错：" + e.getMessage());
            e.printStackTrace();
        }
    }

    public static Map<String, String> getConfigMap(String signPath) {
        Map<String, String> configMap = new HashMap<>();
        File folder = new File(signPath);
        if (folder.exists() && folder.isDirectory()) {
            File[] imgFiles = folder.listFiles();
            if (imgFiles != null && imgFiles.length > 0) {
                for (File file : imgFiles) {
                    if (file.isFile()) {
                        String name = file.getName().substring(0, file.getName().lastIndexOf('.'));
                        String path = file.getAbsolutePath();
                        configMap.put(name, path);
                    }
                }
            } else {
                System.out.println("该文件夹下没有文件");
                logger.error("该文件夹下没有文件");
            }
        } else {
            System.out.println("没有此文件夹:" + signPath + ",可能是代码的路径与实际路径不对应");
            logger.error("没有此文件夹:" + signPath + ",可能是代码的路径与实际路径不对应");
        }

        return configMap;
    }

    public static void doSignal(PdfContentByte overContent, String imgPath, Float x, Float y,String time ,String x1,String y1) throws DocumentException, IOException {

//        //坐标平移
//        AffineTransform transform = new AffineTransform();
//        PdfDocument pdfDocument = overContent.getPdfDocument();
//        transform.translate(0,pdfDocument.getPageSize().getHeight());
        // overContent.concatCTM(transform);
        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy.M.d");
        SimpleDateFormat outputFormat = new SimpleDateFormat("M/d/yyyy");
        try {
            Date date = inputFormat.parse(time);
            time = outputFormat.format(date);
        } catch ( ParseException e) {
            e.printStackTrace();

        }

        Image img = Image.getInstance(imgPath);
        overContent.saveState();
        PdfGState state = new PdfGState();

        overContent.setGState(state);
        //坐标
        img.setAbsolutePosition(x, y-img.getHeight());
        //签名图片框的大小

        //img.scaleAbsolute(width, height);
        img.scaleAbsolute(img.getWidth(),img.getHeight());

        overContent.addImage(img);

        overContent.restoreState();

        if(NO_NEED.equals(x1) && NO_NEED.equals(y1)){
            logger.info(x1+" "+y1 + "时间不需要签名");
        }else {
            //文字
            FontFactory.registerDirectories();
            Font font = FontFactory.getFont("Times New Roman");
            overContent.beginText();
            overContent.setFontAndSize(font.getBaseFont(),fontSize);
            overContent.showTextAligned(PdfContentByte.ALIGN_LEFT,time,Float.parseFloat(x1),Float.parseFloat(y1)-fontSize,0);
            overContent.endText();
        }

    }

    public static String readFileByCharCode(String filePath, String charCode) throws IOException {
        File file = new File(filePath);
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                Files.newInputStream(file.toPath()), charCode));
        String line;
        StringBuilder sb = new StringBuilder();

        while ((line = reader.readLine()) != null) {

            sb.append(line).append(System.getProperty("line.separator"));

        }
        reader.close();


        return sb.toString();
    }

//    public static Node readSignConfig(String pdfType) throws IOException, SAXException, ParserConfigurationException {
//        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//        DocumentBuilder db = dbf.newDocumentBuilder();
//        Document doc = db.parse(ReadPropertiesUtil.class.getResourceAsStream("/sign_config.xml"));
//        doc.getDocumentElement().normalize();
//        Node tempNode = null;
//        NodeList nodeList = doc.getElementsByTagName("template");
//        for (int i = 0; i < nodeList.getLength(); i++) {
//            Node node = nodeList.item(i);
//            NamedNodeMap attrs = node.getAttributes();
//            if(attrs.getNamedItem("name").getNodeValue().equals(pdfType)){
//                tempNode = node;
//            }
//        }
//        return  tempNode;
//    }

}
